<?php

namespace Kateba\UserBundle\Entity;

use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Kateba\UserBundle\Entity\User
 *
 * @UniqueEntity(fields={"loginName"}, groups={"signup", "edit", "loginName"})
 * @UniqueEntity(fields={"email"}, groups={"signup", "edit", "email"})
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Kateba\UserBundle\Entity\UserRepository")
 * @ORM\HasLifecycleCallbacks
 * @author Mahmoud
 */
class User implements AdvancedUserInterface {

    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \Kateba\SiteBundle\Entity\Message[]
     *
     * @ORM\OneToMany(targetEntity="\Kateba\SiteBundle\Entity\Message", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     */
    private $messages;

    /**
     * @var \Kateba\SiteBundle\Entity\Comment[]
     *
     * @ORM\OneToMany(targetEntity="\Kateba\SiteBundle\Entity\Comment", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     */
    private $comments;

    /**
     * @var \Kateba\SiteBundle\Entity\Question[]
     *
     * @ORM\OneToMany(targetEntity="\Kateba\SiteBundle\Entity\Question", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     */
    private $questions;

    /**
     * @var \Kateba\SiteBundle\Entity\Answer[]
     *
     * @ORM\OneToMany(targetEntity="\Kateba\SiteBundle\Entity\Answer", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     */
    private $answers;

    /**
     * @var \Kateba\SiteBundle\Entity\UserService[]
     *
     * @ORM\OneToMany(targetEntity="\Kateba\SiteBundle\Entity\UserService", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
     */
    private $userServices;

    /**
     * @ORM\ManyToMany(targetEntity="\Kateba\UserBundle\Entity\Role")
     * @ORM\JoinTable(name="user_role",
     *     joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)},
     *     inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)}
     * )
     * @var \Doctrine\Common\Collections\ArrayCollection $userRoles
     */
    private $userRoles;

    /**
     * @var string $loginName
     *
     * @ORM\Column(name="loginName", type="string", length=255, nullable=true, unique=true)
     * @Assert\NotBlank(groups={"signup", "edit", "loginName"})
     * @Assert\Regex(pattern="/^\w+$/u", groups={"signup", "edit", "loginName"}, message="Only characters, numbers and _")
     */
    private $loginName;

    /**
     * @var string $email
     *
     * @ORM\Column(name="email", type="string", length=255, unique=true)
     * @Assert\NotBlank(groups={"signup", "edit", "email"})
     * @Assert\Email(groups={"signup", "edit", "email"})
     */
    private $email;

    /**
     * @var string $password
     *
     * @ORM\Column(name="password", type="string", length=255)
     */
    private $password;

    /**
     * @var string $userPassword
     * @Assert\MinLength(limit=6, groups={"signup", "edit", "password"})
     * @Assert\NotBlank(groups={"signup", "password"})
     */
    private $userPassword;

    /**
     * @var string $oldPassword
     * @Assert\NotBlank(groups={"oldPassword"})
     */
    private $oldPassword;

    /**
     * @var string $confirmationCode
     *
     * @ORM\Column(name="confirmationCode", type="string", length=64)
     */
    private $confirmationCode;

    /**
     * @var date $createdAt
     *
     * @ORM\Column(name="createdAt", type="date")
     */
    private $createdAt;

    /**
     * @var string $firstName
     *
     * @ORM\Column(name="firstName", type="string", length=255, nullable=true)
     */
    private $firstName;

    /**
     * @var string $lastName
     *
     * @ORM\Column(name="lastName", type="string", length=255, nullable=true)
     */
    private $lastName;

    /**
     * @var boolean $messageNotify
     *
     * @ORM\Column(name="messageNotify", type="boolean")
     */
    private $messageNotify = false;

    /**
     * @var string $country
     *
     * @ORM\Column(name="country", type="string", length=255, nullable=true)
     */
    private $country;

    /**
     * @var string $city
     *
     * @ORM\Column(name="city", type="string", length=255, nullable=true)
     */
    private $city;

    /**
     * @var string $state
     *
     * @ORM\Column(name="state", type="string", length=255, nullable=true)
     */
    private $state;

    /**
     * @var string $highestEducationCompleted
     *
     * @ORM\Column(name="highestEducationCompleted", type="string", length=255, nullable=true)
     */
    private $highestEducationCompleted;

    /**
     * @var string $currentGradeLevel
     *
     * @ORM\Column(name="currentGradeLevel", type="string", length=255, nullable=true)
     */
    private $currentGradeLevel;

    /**
     * @var string $currentMajorConcentration
     *
     * @ORM\Column(name="currentMajorConcentration", type="string", length=255, nullable=true)
     */
    private $currentMajorConcentration;

    /**
     * @var string $GPA
     *
     * @ORM\Column(name="GPA", type="string", length=255, nullable=true)
     */
    private $GPA;

    /**
     * @var string $intendedStudyField
     *
     * @ORM\Column(name="intendedStudyField", type="string", length=255, nullable=true)
     */
    private $intendedStudyField;

    /**
     * @var date $expectedEnrollmentSemester
     *
     * @ORM\Column(name="expectedEnrollmentSemester", type="string", length=255, nullable=true)
     */
    private $expectedEnrollmentSemester;

    /**
     * @var string $expectedSemesterEnrollmentDate
     *
     * @ORM\Column(name="expectedSemesterEnrollmentDate", type="string", length=255, nullable=true)
     */
    private $expectedSemesterEnrollmentDate;

    /**
     * @var date $desiredCollegeUniversity
     *
     * @ORM\Column(name="desiredCollegeUniversity", type="string", length=255, nullable=true)
     */
    private $desiredCollegeUniversity;

    /**
     * @var boolean $locked
     * @ORM\Column(name="locked", type="boolean")
     */
    private $locked = FALSE;

    /**
     * @var boolean $enabled
     * @ORM\Column(name="enabled", type="boolean")
     */
    private $enabled = TRUE;

    /**
     * @var boolean $answerNotify
     * @ORM\Column(name="answerNotify", type="boolean")
     */
    private $answerNotify = TRUE;

    /**
     * @var string $salt
     * @ORM\Column(name="salt", type="string", length=255)
     */
    private $salt;

    /**
     * @var integer $newMessagesCount
     *
     * @ORM\Column(name="newMessagesCount", type="integer")
     */
    private $newMessagesCount = 0;

    /**
     * @var integer $newAdminMessagesCount
     *
     * @ORM\Column(name="newAdminMessagesCount", type="integer")
     */
    private $newAdminMessagesCount = 0;

    /**
     * @var string $image
     *
     * @ORM\Column(name="image", type="string", length=20, nullable=true)
     */
    private $image;

    /**
     * a temp variable for storing the old image name to delete the old image after the update
     * @var string $temp
     */
    private $temp;

    /**
     * @Assert\Image(groups={"edit", "image"})
     * @var \Symfony\Component\HttpFoundation\File\UploadedFile
     */
    private $file;

    /**
     * Set image
     *
     * @param string $image
     * @return User
     */
    public function setImage($image) {
        $this->image = $image;
        return $this;
    }

    /**
     * Get image
     *
     * @return string
     */
    public function getImage() {
        return $this->image;
    }

    /**
     * Set file
     *
     * @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
     * @return User
     */
    public function setFile($file) {
        $this->file = $file;
        //check if we have an old image
        if ($this->image) {
            //store the old name to delete on the update
            $this->temp = $this->image;
            $this->image = NULL;
        } else {
            $this->image = 'initial';
        }
        return $this;
    }

    /**
     * Get file
     *
     * @return \Symfony\Component\HttpFoundation\File\UploadedFile
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * this function is used to delete the current image
     * the deleting of the current object will also delete the image and you do not need to call this function
     * if you call this function before you remove the object the image will not be removed
     */
    public function removeImage() {
        //check if we have an old image
        if ($this->image) {
            //store the old name to delete on the update
            $this->temp = $this->image;
            //delete the current image
            $this->image = NULL;
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload() {
        if (NULL !== $this->file && (NULL === $this->image || 'initial' === $this->image)) {
            //get the image extension
            $extension = $this->file->guessExtension();
            //generate a random image name
            $img = uniqid();
            //get the image upload directory
            $uploadDir = $this->getUploadRootDir();
            //check if the upload directory exists
            if (!@is_dir($uploadDir)) {
                //get the old umask
                $oldumask = umask(0);
                //not a directory probably the first time try to create the directory
                $success = @mkdir($uploadDir, 0755, TRUE);
                //reset the umask
                umask($oldumask);
                //check if we created the folder
                if (!$success) {
                    //could not create the folder throw an exception to stop the insert
                    throw new \Exception("Can not create the directory $uploadDir");
                }
            }
            //check that the file name does not exist
            while (@file_exists("$uploadDir/$img.$extension")) {
                //try to find a new unique name
                $img = uniqid();
            }
            //set the image new name
            $this->image = "$img.$extension";
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload() {
        if (NULL !== $this->file) {
            // you must throw an exception here if the file cannot be moved
            // so that the entity is not persisted to the database
            // which the UploadedFile move() method does
            $this->file->move($this->getUploadRootDir(), $this->image);
            //remove the file as you do not need it any more
            $this->file = NULL;
        }
        //check if we have an old image
        if ($this->temp) {
            //try to delete the old image
            @unlink($this->getUploadRootDir() . '/' . $this->temp);
            //clear the temp image
            $this->temp = NULL;
        }
    }

    /**
     * @ORM\PostRemove()
     */
    public function postRemove() {
        //check if we have an image
        if ($this->image) {
            //try to delete the image
            @unlink($this->getAbsolutePath());
        }
    }

    /**
     * @return string the path of image starting of root
     */
    public function getAbsolutePath() {
        return $this->getUploadRootDir() . '/' . $this->image;
    }

    /**
     * @return string the relative path of image starting from web directory
     */
    public function getWebPath() {
        return NULL === $this->image ? NULL : '/' . $this->getUploadDir() . '/' . $this->image;
    }

    /**
     * @return string the path of upload directory starting of root
     */
    public function getUploadRootDir() {
        // the absolute directory path where uploaded documents should be saved
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }

    /**
     * @param $width the desired image width
     * @param $height the desired image height
     * @return string the htaccess file url pattern which map to timthumb url
     */
    public function getSmallImageUrl($width = 50, $height = 50) {
        return NULL === $this->image ? NULL : "/user-image/$width/$height/$this->image";
    }

    /**
     * @return string the document upload directory path starting from web folder
     */
    private function getUploadDir() {
        return 'uploads/users-images';
    }

    /**
     * initialize the main default attributes
     */
    public function __construct() {
        $this->createdAt = new \DateTime();
        $this->confirmationCode = md5(uniqid(rand()));
        $this->salt = md5(time());
        $this->userRoles = new ArrayCollection();
        $this->comments = new ArrayCollection();
        $this->questions = new ArrayCollection();
        $this->answers = new ArrayCollection();
        $this->messages = new ArrayCollection();
        $this->userServices = new ArrayCollection();
    }

    /**
     * @return string the object name
     */
    public function __toString() {
//        if ($this->lastName) {
//            return "$this->firstName $this->lastName";
//        } elseif ($this->firstName) {
//            return $this->firstName;
//        } else {
            return (string) $this->loginName;
//        }
    }

    /**
     * this function is used by php to know which attributes to serialize
     * the returned array must not contain any one to one or one to many relation object
     * @return array
     */
    public function __sleep() {
        return array(
            'id', 'loginName', 'email', 'password', 'confirmationCode', 'answerNotify',
            'createdAt', 'messageNotify', 'firstName', 'lastName', 'country',
            'locked', 'enabled', 'salt', 'image', 'newMessagesCount', 'newAdminMessagesCount',
            'city', 'state', 'highestEducationCompleted', 'currentGradeLevel',
            'currentMajorConcentration', 'GPA', 'intendedStudyField', 'expectedEnrollmentSemester',
            'expectedSemesterEnrollmentDate', 'desiredCollegeUniversity'
        );
    }

    /**
     * this function will set a valid random password for the user
     */
    public function setRandomPassword() {
        $this->setUserPassword(rand());
    }

    /**
     * this function will set the valid password for the user
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function setValidPassword() {
        //check if we have a password
        if ($this->getUserPassword()) {
            //hash the password
            $this->setPassword($this->hashPassword($this->getUserPassword()));
        } else {
            //check if the object is new
            if ($this->getId() === NULL) {
                //new object set a random password
                $this->setRandomPassword();
                //hash the password
                $this->setPassword($this->hashPassword($this->getUserPassword()));
            }
        }
    }

    /**
     * this function will hash a password and return the hashed value
     * the encoding has to be the same as the one in the project security.yml file
     * @param string $password the password to return it is hash
     */
    private function hashPassword($password) {
        //create an encoder object
        $encoder = new MessageDigestPasswordEncoder('sha512', true, 10);
        //return the hashed password
        return $encoder->encodePassword($password, $this->getSalt());
    }

    /**
     * this function will check if the user entered a valid old password
     * @Assert\True(message = "the old password is wrong", groups={"oldPassword"})
     */
    public function isOldPasswordCorrect() {
        if ($this->hashPassword($this->getOldPassword()) == $this->getPassword()) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * Set oldPassword
     *
     * @param string $oldPassword
     */
    public function setOldPassword($oldPassword) {
        $this->oldPassword = $oldPassword;
    }

    /**
     * Get oldPassword
     *
     * @return string
     */
    public function getOldPassword() {
        return $this->oldPassword;
    }

    /**
     * Set userPassword
     *
     * @param string $password
     */
    public function setUserPassword($password) {
        $this->userPassword = $password;
    }

    /**
     * @return string the user password
     */
    public function getUserPassword() {
        return $this->userPassword;
    }

    /**
     * Implementation of getRoles for the UserInterface.
     *
     * @return array An array of Roles
     */
    public function getRoles() {
        return $this->getUserRoles()->toArray();
    }

    /**
     * Implementation of eraseCredentials for the UserInterface.
     */
    public function eraseCredentials() {
        //remove the user password
        $this->userPassword = null;
        $this->oldPassword = null;
    }

    /**
     * Implementation of getPassword for the UserInterface.
     * @return string the hashed user password
     */
    public function getPassword() {
        return $this->password;
    }

    /**
     * Implementation of getSalt for the UserInterface.
     * @return string the user salt
     */
    public function getSalt() {
        return $this->salt;
    }

    /**
     * Implementation of getUsername for the UserInterface.
     * check security.yml to know the used column by the firewall
     * @return string the user name used by the firewall configurations.
     */
    public function getUsername() {
        return $this->loginName;
    }

    /**
     * Implementation of isAccountNonExpired for the AdvancedUserInterface.
     * @return boolean
     */
    public function isAccountNonExpired() {
        return TRUE;
    }

    /**
     * Implementation of isCredentialsNonExpired for the AdvancedUserInterface.
     * @return boolean
     */
    public function isCredentialsNonExpired() {
        return TRUE;
    }

    /**
     * Implementation of isAccountNonLocked for the AdvancedUserInterface.
     * @return boolean
     */
    public function isAccountNonLocked() {
        return !$this->locked;
    }

    /**
     * Implementation of isEnabled for the AdvancedUserInterface.
     * @return boolean
     */
    public function isEnabled() {
        return $this->enabled;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set loginName
     *
     * @param string $loginName
     */
    public function setLoginName($loginName) {
        $this->loginName = $loginName;
    }

    /**
     * Get loginName
     *
     * @return string
     */
    public function getLoginName() {
        return $this->loginName;
    }

    /**
     * Set email
     *
     * @param string $email
     */
    public function setEmail($email) {
        $this->email = $email;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail() {
        return $this->email;
    }

    /**
     * Set password
     *
     * @param string $password
     */
    public function setPassword($password) {
        $this->password = $password;
    }

    /**
     * Set confirmationCode
     *
     * @param string $confirmationCode
     */
    public function setConfirmationCode($confirmationCode) {
        $this->confirmationCode = $confirmationCode;
    }

    /**
     * Get confirmationCode
     *
     * @return string
     */
    public function getConfirmationCode() {
        return $this->confirmationCode;
    }

    /**
     * Get createdAt
     *
     * @return date
     */
    public function getCreatedAt() {
        return $this->createdAt;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     */
    public function setFirstName($firstName) {
        $this->firstName = $firstName;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName() {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     */
    public function setLastName($lastName) {
        $this->lastName = $lastName;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName() {
        return $this->lastName;
    }

    /**
     * Set country
     *
     * @param string $country
     */
    public function setCountry($country) {
        $this->country = $country;
    }

    /**
     * Get country
     *
     * @return string
     */
    public function getCountry() {
        return $this->country;
    }

    /**
     * Set locked
     *
     * @param boolean $locked
     */
    public function setLocked($locked) {
        $this->locked = $locked;
    }

    /**
     * Get locked
     *
     * @return boolean
     */
    public function getLocked() {
        return $this->locked;
    }

    /**
     * Set enabled
     *
     * @param boolean $enabled
     */
    public function setEnabled($enabled) {
        $this->enabled = $enabled;
    }

    /**
     * Get enabled
     *
     * @return boolean
     */
    public function getEnabled() {
        return $this->enabled;
    }

    /**
     * Set salt
     *
     * @param string $salt
     */
    public function setSalt($salt) {
        $this->salt = $salt;
    }

    /**
     * Add userRoles
     *
     * @param Kateba\UserBundle\Entity\Role $userRoles
     */
    public function addRole(\Kateba\UserBundle\Entity\Role $userRoles) {
        if (!$this->userRoles->contains($userRoles)) {
            $this->userRoles[] = $userRoles;
        }
    }

    /**
     * Get userRoles
     *
     * @return Doctrine\Common\Collections\Collection
     */
    public function getUserRoles() {
        return $this->userRoles;
    }

    /**
     * Add userRoles
     *
     * @param \Kateba\UserBundle\Entity\Role $userRoles
     * @return User
     */
    public function addUserRole(\Kateba\UserBundle\Entity\Role $userRoles) {
        $this->userRoles[] = $userRoles;

        return $this;
    }

    /**
     * Remove userRoles
     *
     * @param \Kateba\UserBundle\Entity\Role $userRoles
     */
    public function removeUserRole(\Kateba\UserBundle\Entity\Role $userRoles) {
        $this->userRoles->removeElement($userRoles);
    }

    /**
     * Add comments
     *
     * @param \Kateba\SiteBundle\Entity\Comment $comments
     * @return User
     */
    public function addComment(\Kateba\SiteBundle\Entity\Comment $comments) {
        $this->comments[] = $comments;

        return $this;
    }

    /**
     * Remove comments
     *
     * @param \Kateba\SiteBundle\Entity\Comment $comments
     */
    public function removeComment(\Kateba\SiteBundle\Entity\Comment $comments) {
        $this->comments->removeElement($comments);
    }

    /**
     * Get comments
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getComments() {
        return $this->comments;
    }

    /**
     * Add questions
     *
     * @param \Kateba\SiteBundle\Entity\Question $questions
     * @return User
     */
    public function addQuestion(\Kateba\SiteBundle\Entity\Question $questions) {
        $this->questions[] = $questions;

        return $this;
    }

    /**
     * Remove questions
     *
     * @param \Kateba\SiteBundle\Entity\Question $questions
     */
    public function removeQuestion(\Kateba\SiteBundle\Entity\Question $questions) {
        $this->questions->removeElement($questions);
    }

    /**
     * Get questions
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getQuestions() {
        return $this->questions;
    }

    /**
     * Add answers
     *
     * @param \Kateba\SiteBundle\Entity\Answer $answers
     * @return User
     */
    public function addAnswer(\Kateba\SiteBundle\Entity\Answer $answers) {
        $this->answers[] = $answers;

        return $this;
    }

    /**
     * Remove answers
     *
     * @param \Kateba\SiteBundle\Entity\Answer $answers
     */
    public function removeAnswer(\Kateba\SiteBundle\Entity\Answer $answers) {
        $this->answers->removeElement($answers);
    }

    /**
     * Get answers
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getAnswers() {
        return $this->answers;
    }

    /**
     * Add userServices
     *
     * @param \Kateba\SiteBundle\Entity\UserService $userServices
     * @return User
     */
    public function addUserService(\Kateba\SiteBundle\Entity\UserService $userServices) {
        $this->userServices[] = $userServices;

        return $this;
    }

    /**
     * Remove userServices
     *
     * @param \Kateba\SiteBundle\Entity\UserService $userServices
     */
    public function removeUserService(\Kateba\SiteBundle\Entity\UserService $userServices) {
        $this->userServices->removeElement($userServices);
    }

    /**
     * Get userServices
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUserServices() {
        return $this->userServices;
    }

    /**
     * Add messages
     *
     * @param \Kateba\SiteBundle\Entity\Message $messages
     * @return User
     */
    public function addMessage(\Kateba\SiteBundle\Entity\Message $messages) {
        $this->messages[] = $messages;

        return $this;
    }

    /**
     * Remove messages
     *
     * @param \Kateba\SiteBundle\Entity\Message $messages
     */
    public function removeMessage(\Kateba\SiteBundle\Entity\Message $messages) {
        $this->messages->removeElement($messages);
    }

    /**
     * Get messages
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getMessages() {
        return $this->messages;
    }

    /**
     * Set newMessagesCount
     *
     * @param integer $newMessagesCount
     * @return User
     */
    public function setNewMessagesCount($newMessagesCount) {
        $this->newMessagesCount = $newMessagesCount;

        return $this;
    }

    /**
     * Get newMessagesCount
     *
     * @return integer
     */
    public function getNewMessagesCount() {
        return $this->newMessagesCount;
    }

    /**
     * Set messageNotify
     *
     * @param boolean $messageNotify
     * @return User
     */
    public function setMessageNotify($messageNotify) {
        $this->messageNotify = $messageNotify;

        return $this;
    }

    /**
     * Get messageNotify
     *
     * @return boolean
     */
    public function getMessageNotify() {
        return $this->messageNotify;
    }

    /**
     * Set newAdminMessagesCount
     *
     * @param integer $newAdminMessagesCount
     * @return User
     */
    public function setNewAdminMessagesCount($newAdminMessagesCount) {
        $this->newAdminMessagesCount = $newAdminMessagesCount;

        return $this;
    }

    /**
     * Get newAdminMessagesCount
     *
     * @return integer
     */
    public function getNewAdminMessagesCount() {
        return $this->newAdminMessagesCount;
    }

    /**
     * Set answerNotify
     *
     * @param boolean $answerNotify
     * @return User
     */
    public function setAnswerNotify($answerNotify) {
        $this->answerNotify = $answerNotify;

        return $this;
    }

    /**
     * Get answerNotify
     *
     * @return boolean
     */
    public function getAnswerNotify() {
        return $this->answerNotify;
    }

    public function getValidHighestEducationCompleted() {
        return array(
            "Associate's Degree" => "Associate's Degree",
            "Certificate Program" => "Certificate Program",
            "Doctor of Medicine" => "Doctor of Medicine",
            "Doctoral Degree" => "Doctoral Degree",
            "High School Diploma" => "High School Diploma",
            "Juris Doctor" => "Juris Doctor",
            "Master's Degree" => "Master's Degree",
            "Other" => "Other",
            "Post Doctorate" => "Post Doctorate",
            "Primary Education" => "Primary Education",
            "Specialist Degree" => "Specialist Degree"
        );
    }

    public function getValidCurrentMajorConcentration() {
        return array(
            "Agriculture" => "Agriculture",
            "Anthropology" => "Anthropology",
            "Architecture" => "Architecture",
            "Arts – Other" => "Arts – Other",
            "Arts – Performing" => "Arts – Performing",
            "Arts – Visual" => "Arts – Visual",
            "Astronomy" => "Astronomy",
            "Biology" => "Biology",
            "Business – Accounting" => "Business – Accounting",
            "Business – Finance" => "Business – Finance",
            "Business – Management" => "Business – Management",
            "Business – Marketing" => "Business – Marketing",
            "Business – Other" => "Business – Other",
            "Chemistry" => "Chemistry",
            "Communications/Media" => "Communications/Media",
            "Computer Science/MIS" => "Computer Science/MIS",
            "Creative Writing" => "Creative Writing",
            "Criminal Justice" => "Criminal Justice",
            "Design" => "Design",
            "Economics" => "Economics",
            "Education – Early Childhood" => "Education – Early Childhood",
            "Education – Elementary" => "Education – Elementary",
            "Education – Higher Education" => "Education – Higher Education",
            "Education – Other" => "Education – Other",
            "Education – Secondary" => "Education – Secondary",
            "Education – Special Needs" => "Education – Special Needs",
            "Engineering – Aeronautical" => "Engineering – Aeronautical",
            "Engineering – Chemical" => "Engineering – Chemical",
            "Engineering – Civil" => "Engineering – Civil",
            "Engineering – Electrical" => "Engineering – Electrical",
            "Engineering – Industrial" => "Engineering – Industrial",
            "Engineering – Mechanical" => "Engineering – Mechanical",
            "Engineering – Other" => "Engineering – Other",
            "Engineering Technology – Electronic" => "Engineering Technology – Electronic",
            "Engineering Technology – Mechanical" => "Engineering Technology – Mechanical",
            "Engineering Technology – Other" => "Engineering Technology – Other",
            "English/Literature" => "English/Literature",
            "Environment" => "Environment",
            "Ethnic Studies" => "Ethnic Studies",
            "Fashion" => "Fashion",
            "Geography" => "Geography",
            "Health/Medical" => "Health/Medical",
            "History" => "History",
            "Hospitality" => "Hospitality",
            "Human Services" => "Human Services",
            "Language" => "Language",
            "Law" => "Law",
            "Library and Information Science" => "Library and Information Science",
            "Mathematics" => "Mathematics",
            "Nursing" => "Nursing",
            "Philosophy" => "Philosophy",
            "Physical Therapy" => "Physical Therapy",
            "Political Science/Government" => "Political Science/Government",
            "Psychology" => "Psychology",
            "Public Health" => "Public Health",
            "Religion/Theology" => "Religion/Theology",
            "Science – Life" => "Science – Life",
            "Science – Marine" => "Science – Marine",
            "Science – Other" => "Science – Other",
            "Science – Physical" => "Science – Physical",
            "Sociology" => "Sociology",
            "Social Science" => "Social Science",
            "Social Work" => "Social Work",
            "Sports/Recreation" => "Sports/Recreation",
            "Women's Studies" => "Women's Studies",
            "Other" => "Other",
            "Undeclared" => "Undeclared"
        );
    }

    public function getValidIntendedStudyField() {
        return array(
            "Agriculture" => "Agriculture",
            "Anthropology" => "Anthropology",
            "Architecture" => "Architecture",
            "Arts – Other" => "Arts – Other",
            "Arts – Performing" => "Arts – Performing",
            "Arts – Visual" => "Arts – Visual",
            "Astronomy" => "Astronomy",
            "Biology" => "Biology",
            "Business – Accounting" => "Business – Accounting",
            "Business – Finance" => "Business – Finance",
            "Business – Management" => "Business – Management",
            "Business – Marketing" => "Business – Marketing",
            "Business – Other" => "Business – Other",
            "Chemistry" => "Chemistry",
            "Communications/Media" => "Communications/Media",
            "Computer Science/MIS" => "Computer Science/MIS",
            "Creative Writing" => "Creative Writing",
            "Criminal Justice" => "Criminal Justice",
            "Design" => "Design",
            "Economics" => "Economics",
            "Education – Early Childhood" => "Education – Early Childhood",
            "Education – Elementary" => "Education – Elementary",
            "Education – Higher Education" => "Education – Higher Education",
            "Education – Other" => "Education – Other",
            "Education – Secondary" => "Education – Secondary",
            "Education – Special Needs" => "Education – Special Needs",
            "Engineering – Aeronautical" => "Engineering – Aeronautical",
            "Engineering – Chemical" => "Engineering – Chemical",
            "Engineering – Civil" => "Engineering – Civil",
            "Engineering – Electrical" => "Engineering – Electrical",
            "Engineering – Industrial" => "Engineering – Industrial",
            "Engineering – Mechanical" => "Engineering – Mechanical",
            "Engineering – Other" => "Engineering – Other",
            "Engineering Technology – Electronic" => "Engineering Technology – Electronic",
            "Engineering Technology – Mechanical" => "Engineering Technology – Mechanical",
            "Engineering Technology – Other" => "Engineering Technology – Other",
            "English/Literature" => "English/Literature",
            "Environment" => "Environment",
            "Ethnic Studies" => "Ethnic Studies",
            "Fashion" => "Fashion",
            "Geography" => "Geography",
            "Health/Medical" => "Health/Medical",
            "History" => "History",
            "Hospitality" => "Hospitality",
            "Human Services" => "Human Services",
            "Language" => "Language",
            "Law" => "Law",
            "Library and Information Science" => "Library and Information Science",
            "Mathematics" => "Mathematics",
            "Nursing" => "Nursing",
            "Philosophy" => "Philosophy",
            "Physical Therapy" => "Physical Therapy",
            "Political Science/Government" => "Political Science/Government",
            "Psychology" => "Psychology",
            "Public Health" => "Public Health",
            "Religion/Theology" => "Religion/Theology",
            "Science – Life" => "Science – Life",
            "Science – Marine" => "Science – Marine",
            "Science – Other" => "Science – Other",
            "Science – Physical" => "Science – Physical",
            "Sociology" => "Sociology",
            "Social Science" => "Social Science",
            "Social Work" => "Social Work",
            "Sports/Recreation" => "Sports/Recreation",
            "Women's Studies" => "Women's Studies",
            "Other" => "Other",
            "Undecided" => "Undecided"
        );
    }

    public function getValidCountry() {
        return array(
            "Afghanistan" => "Afghanistan",
            "Aland Islands" => "Aland Islands",
            "Albania" => "Albania",
            "Algeria" => "Algeria",
            "American Samoa" => "American Samoa",
            "Andorra" => "Andorra",
            "Angola" => "Angola",
            "Anguilla" => "Anguilla",
            "Antarctica" => "Antarctica",
            "Antigua and Barbuda" => "Antigua and Barbuda",
            "Argentina" => "Argentina",
            "Armenia" => "Armenia",
            "Aruba" => "Aruba",
            "Australia" => "Australia",
            "Austria" => "Austria",
            "Azerbaijan" => "Azerbaijan",
            "Bahamas" => "Bahamas",
            "Bahrain" => "Bahrain",
            "Bangladesh" => "Bangladesh",
            "Barbados" => "Barbados",
            "Belarus" => "Belarus",
            "Belgium" => "Belgium",
            "Belize" => "Belize",
            "Benin" => "Benin",
            "Bermuda" => "Bermuda",
            "Bhutan" => "Bhutan",
            "Bolivia, Plurinational State of" => "Bolivia, Plurinational State of",
            "Bonaire, Sint Eustatius and Saba" => "Bonaire, Sint Eustatius and Saba",
            "Bosnia and Herzegovina" => "Bosnia and Herzegovina",
            "Botswana" => "Botswana",
            "Bouvet Island" => "Bouvet Island",
            "Brazil" => "Brazil",
            "British Indian Ocean Territory" => "British Indian Ocean Territory",
            "Brunei Darussalam" => "Brunei Darussalam",
            "Bulgaria" => "Bulgaria",
            "Burkina Faso" => "Burkina Faso",
            "Burundi" => "Burundi",
            "Cambodia" => "Cambodia",
            "Cameroon" => "Cameroon",
            "Canada" => "Canada",
            "Cape Verde" => "Cape Verde",
            "Cayman Islands" => "Cayman Islands",
            "Central African Republic" => "Central African Republic",
            "Chad" => "Chad",
            "Chile" => "Chile",
            "China" => "China",
            "Christmas Island" => "Christmas Island",
            "Cocos (Keeling) Islands" => "Cocos (Keeling) Islands",
            "Colombia" => "Colombia",
            "Comoros" => "Comoros",
            "Congo, The Democratic Republic of The" => "Congo, The Democratic Republic of The",
            "Cook Islands" => "Cook Islands",
            "Costa Rica" => "Costa Rica",
            "Cote D’Ivoire" => "Cote D’Ivoire",
            "Croatia" => "Croatia",
            "Cuba" => "Cuba",
            "Curacao" => "Curacao",
            "Cyprus" => "Cyprus",
            "Czech Republics" => "Czech Republics",
            "Denmark" => "Denmark",
            "Djibouti" => "Djibouti",
            "Dominica" => "Dominica",
            "Dominican Republic" => "Dominican Republic",
            "Ecuador" => "Ecuador",
            "Egypt" => "Egypt",
            "El Salvador" => "El Salvador",
            "Equatorial Guinea" => "Equatorial Guinea",
            "Eritrea" => "Eritrea",
            "Estonia" => "Estonia",
            "Ethiopia" => "Ethiopia",
            "Falkland Islands (Malvinas)" => "Falkland Islands (Malvinas)",
            "Faroe Islands" => "Faroe Islands",
            "Fiji" => "Fiji",
            "Finland" => "Finland",
            "France" => "France",
            "French Guiana" => "French Guiana",
            "French Polynesia" => "French Polynesia",
            "Gabon" => "Gabon",
            "Gambia" => "Gambia",
            "Georgia" => "Georgia",
            "Germany" => "Germany",
            "Ghana" => "Ghana",
            "Gibraltar" => "Gibraltar",
            "Greece" => "Greece",
            "Greenland" => "Greenland",
            "Grenada" => "Grenada",
            "Guadeloupe" => "Guadeloupe",
            "Guam" => "Guam",
            "Guatemala" => "Guatemala",
            "Guernsey" => "Guernsey",
            "Guinea-Bissau" => "Guinea-Bissau",
            "Guyana" => "Guyana",
            "Haiti" => "Haiti",
            "Heard Island and Mcdonald Islands" => "Heard Island and Mcdonald Islands",
            "Holy See (Vatican City State)" => "Holy See (Vatican City State)",
            "Honduras" => "Honduras",
            "Hong Kong" => "Hong Kong",
            "Hungary" => "Hungary",
            "Iceland" => "Iceland",
            "India" => "India",
            "Indonesia" => "Indonesia",
            "Iran, Islamic Republic Of" => "Iran, Islamic Republic Of",
            "Iraq" => "Iraq",
            "Ireland" => "Ireland",
            "Isle of Man" => "Isle of Man",
            "Israel" => "Israel",
            "Italy" => "Italy",
            "Jamaica" => "Jamaica",
            "Japan" => "Japan",
            "Jersey" => "Jersey",
            "Jordan" => "Jordan",
            "Kazakhstan" => "Kazakhstan",
            "Kenya" => "Kenya",
            "Kiribati" => "Kiribati",
            "Korea, Democratic People’s Republic Of" => "Korea, Democratic People’s Republic Of",
            "Korea, Republic Of" => "Korea, Republic Of",
            "Kosovo" => "Kosovo",
            "Kuwait" => "Kuwait",
            "Kyrgyzstan" => "Kyrgyzstan",
            "Lao People’s Democratic Republic" => "Lao People’s Democratic Republic",
            "Latvia" => "Latvia",
            "Lebanon" => "Lebanon",
            "Lesotho" => "Lesotho",
            "Liberia" => "Liberia",
            "Liechtenstein" => "Liechtenstein",
            "Lithuania" => "Lithuania",
            "Luxembourg" => "Luxembourg",
            "Macao" => "Macao",
            "Macedonia, The Former Yugoslav Republic Of" => "Macedonia, The Former Yugoslav Republic Of",
            "Madagascar" => "Madagascar",
            "Malawi" => "Malawi",
            "Malaysia" => "Malaysia",
            "Maldives" => "Maldives",
            "Mali" => "Mali",
            "Malta" => "Malta",
            "Marshall Islands" => "Marshall Islands",
            "Martinique" => "Martinique",
            "Mauritania" => "Mauritania",
            "Mauritius" => "Mauritius",
            "Mayotte" => "Mayotte",
            "Mexico" => "Mexico",
            "Micronesia, Federated States Of" => "Micronesia, Federated States Of",
            "Moldova, Republic Of" => "Moldova, Republic Of",
            "Monaco" => "Monaco",
            "Mongolia" => "Mongolia",
            "Montenegro" => "Montenegro",
            "Montserrat" => "Montserrat",
            "Morocco" => "Morocco",
            "Mozambique" => "Mozambique",
            "Myanmar" => "Myanmar",
            "Namibia" => "Namibia",
            "Nauru" => "Nauru",
            "Nepal" => "Nepal",
            "Netherlands" => "Netherlands",
            "New Caledonia" => "New Caledonia",
            "New Zealand" => "New Zealand",
            "Nicaragua" => "Nicaragua",
            "Niger" => "Niger",
            "Nigeria" => "Nigeria",
            "Niue" => "Niue",
            "Norfolk Island" => "Norfolk Island",
            "Northern Mariana Islands" => "Northern Mariana Islands",
            "Norway" => "Norway",
            "Oman" => "Oman",
            "Pakistan" => "Pakistan",
            "Palau" => "Palau",
            "Palestine" => "Palestine",
            "Panama" => "Panama",
            "Papua New Guinea" => "Papua New Guinea",
            "Paraguay" => "Paraguay",
            "Peru" => "Peru",
            "Philippines" => "Philippines",
            "Pitcairn" => "Pitcairn",
            "Poland" => "Poland",
            "Portugal" => "Portugal",
            "Puerto Rico" => "Puerto Rico",
            "Qatar" => "Qatar",
            "Romania" => "Romania",
            "Russian Federation" => "Russian Federation",
            "Rwanda" => "Rwanda",
            "Saint Barthélemy" => "Saint Barthélemy",
            "Saint Helena, Ascension and Tristan Da Cunha" => "Saint Helena, Ascension and Tristan Da Cunha",
            "Saint Kitts and Nevis" => "Saint Kitts and Nevis",
            "Saint Lucia" => "Saint Lucia",
            "Saint Martin (French Part)" => "Saint Martin (French Part)",
            "Saint Pierre and Miquelon" => "Saint Pierre and Miquelon",
            "Saint Vincent And The Grenadines" => "Saint Vincent And The Grenadines",
            "Samoa" => "Samoa",
            "San Marino" => "San Marino",
            "Sao Tome And Principe" => "Sao Tome And Principe",
            "Saudi Arabia" => "Saudi Arabia",
            "Senegal" => "Senegal",
            "Serbia" => "Serbia",
            "Seychelles" => "Seychelles",
            "Sierra Leone" => "Sierra Leone",
            "Singapore" => "Singapore",
            "Sint Maarten (Dutch Part)" => "Sint Maarten (Dutch Part)",
            "Slovakia" => "Slovakia",
            "Slovenia" => "Slovenia",
            "Solomon Islands" => "Solomon Islands",
            "Somalia" => "Somalia",
            "South Africa" => "South Africa",
            "South Georgia And The South Sandwich Islands" => "South Georgia And The South Sandwich Islands",
            "South Sudan" => "South Sudan",
            "Spain" => "Spain",
            "Sri Lanka" => "Sri Lanka",
            "Sudan" => "Sudan",
            "Suriname" => "Suriname",
            "Svalbard And Jan Mayen" => "Svalbard And Jan Mayen",
            "Swaziland" => "Swaziland",
            "Sweden" => "Sweden",
            "Switzerland" => "Switzerland",
            "Syrian Arab Republic" => "Syrian Arab Republic",
            "Taiwan, Province Of China" => "Taiwan, Province Of China",
            "Tajikistan" => "Tajikistan",
            "Tanzania, United Republic of" => "Tanzania, United Republic of",
            "Thailand" => "Thailand",
            "Timor-Leste" => "Timor-Leste",
            "Togo" => "Togo",
            "Tokelau" => "Tokelau",
            "Tonga" => "Tonga",
            "Trinidad and Tobago" => "Trinidad and Tobago",
            "Tunisia" => "Tunisia",
            "Turkey" => "Turkey",
            "Turkmenistan" => "Turkmenistan",
            "Turks And Caicos Islands" => "Turks And Caicos Islands",
            "Tuvalu" => "Tuvalu",
            "Uganda" => "Uganda",
            "Ukraine" => "Ukraine",
            "United Arab Emirates" => "United Arab Emirates",
            "United Kingdom" => "United Kingdom",
            "United States Minor Outlying Islands" => "United States Minor Outlying Islands",
            "Uruguay" => "Uruguay",
            "Uzbekistan" => "Uzbekistan",
            "Vanuatu" => "Vanuatu",
            "Venezuela, Bolivarian Republic Of" => "Venezuela, Bolivarian Republic Of",
            "Vietnam" => "Vietnam",
            "Virgin Islands, British" => "Virgin Islands, British",
            "Virgin Islands, U.S." => "Virgin Islands, U.S.",
            "Wallis And Futuna" => "Wallis And Futuna",
            "Western Sahara" => "Western Sahara",
            "Yemen" => "Yemen",
            "Zambia" => "Zambia",
            "Zimbabwe" => "Zimbabwe",
            "Other" => "Other"
        );
    }

    public function getValidExpectedEnrollmentSemester() {
        return array(
            'Spring' => 'Spring',
            'Fall' => 'Fall'
        );
    }

    public function getValidGPA() {
        $degreesValues = range(0.00, 4.50, .01);
        $degrees = array();
        foreach ($degreesValues as $degree) {
            $degrees["$degree"] = $degree;
        }
        return $degrees;
    }

    public function getValidCurrentGradeLevel() {
        $degreesValues = range(0, 12);
        $degrees = array();
        foreach ($degreesValues as $degree) {
            $degrees["$degree"] = $degree;
        }
        return $degrees;
    }

    /**
     * Set city
     *
     * @param string $city
     * @return User
     */
    public function setCity($city) {
        $this->city = $city;

        return $this;
    }

    /**
     * Get city
     *
     * @return string
     */
    public function getCity() {
        return $this->city;
    }

    /**
     * Set state
     *
     * @param string $state
     * @return User
     */
    public function setState($state) {
        $this->state = $state;

        return $this;
    }

    /**
     * Get state
     *
     * @return string
     */
    public function getState() {
        return $this->state;
    }

    /**
     * Set highestEducationCompleted
     *
     * @param string $highestEducationCompleted
     * @return User
     */
    public function setHighestEducationCompleted($highestEducationCompleted) {
        $this->highestEducationCompleted = $highestEducationCompleted;

        return $this;
    }

    /**
     * Get highestEducationCompleted
     *
     * @return string
     */
    public function getHighestEducationCompleted() {
        return $this->highestEducationCompleted;
    }

    /**
     * Set currentGradeLevel
     *
     * @param string $currentGradeLevel
     * @return User
     */
    public function setCurrentGradeLevel($currentGradeLevel) {
        $this->currentGradeLevel = $currentGradeLevel;

        return $this;
    }

    /**
     * Get currentGradeLevel
     *
     * @return string
     */
    public function getCurrentGradeLevel() {
        return $this->currentGradeLevel;
    }

    /**
     * Set currentMajorConcentration
     *
     * @param string $currentMajorConcentration
     * @return User
     */
    public function setCurrentMajorConcentration($currentMajorConcentration) {
        $this->currentMajorConcentration = $currentMajorConcentration;

        return $this;
    }

    /**
     * Get currentMajorConcentration
     *
     * @return string
     */
    public function getCurrentMajorConcentration() {
        return $this->currentMajorConcentration;
    }

    /**
     * Set GPA
     *
     * @param string $gPA
     * @return User
     */
    public function setGPA($gPA) {
        $this->GPA = $gPA;

        return $this;
    }

    /**
     * Get GPA
     *
     * @return string
     */
    public function getGPA() {
        return $this->GPA;
    }

    /**
     * Set intendedStudyField
     *
     * @param string $intendedStudyField
     * @return User
     */
    public function setIntendedStudyField($intendedStudyField) {
        $this->intendedStudyField = $intendedStudyField;

        return $this;
    }

    /**
     * Get intendedStudyField
     *
     * @return string
     */
    public function getIntendedStudyField() {
        return $this->intendedStudyField;
    }

    /**
     * Set expectedEnrollmentSemester
     *
     * @param string $expectedEnrollmentSemester
     * @return User
     */
    public function setExpectedEnrollmentSemester($expectedEnrollmentSemester) {
        $this->expectedEnrollmentSemester = $expectedEnrollmentSemester;

        return $this;
    }

    /**
     * Get expectedEnrollmentSemester
     *
     * @return string
     */
    public function getExpectedEnrollmentSemester() {
        return $this->expectedEnrollmentSemester;
    }

    /**
     * Set expectedSemesterEnrollmentDate
     *
     * @param string $expectedSemesterEnrollmentDate
     * @return User
     */
    public function setExpectedSemesterEnrollmentDate($expectedSemesterEnrollmentDate) {
        $this->expectedSemesterEnrollmentDate = $expectedSemesterEnrollmentDate;

        return $this;
    }

    /**
     * Get expectedSemesterEnrollmentDate
     *
     * @return string
     */
    public function getExpectedSemesterEnrollmentDate() {
        return $this->expectedSemesterEnrollmentDate;
    }

    /**
     * Set desiredCollegeUniversity
     *
     * @param string $desiredCollegeUniversity
     * @return User
     */
    public function setDesiredCollegeUniversity($desiredCollegeUniversity) {
        $this->desiredCollegeUniversity = $desiredCollegeUniversity;

        return $this;
    }

    /**
     * Get desiredCollegeUniversity
     *
     * @return string
     */
    public function getDesiredCollegeUniversity() {
        return $this->desiredCollegeUniversity;
    }

    /**
     * @return string
     */
    public function getDesiredCollegeUniversities() {
        return json_encode(explode(',', $this->desiredCollegeUniversity));
    }

    /**
     * @return string
     */
    public function getIntendedStudyFields() {
        return json_encode(explode(',', $this->intendedStudyField));
    }

    /**
     * @return array
     */
    public function getValidExpectedSemesterEnrollmentYears() {
        $years = array();
        foreach (range(2013, 2023) as $year) {
            $years[$year] = $year;
        }
        return $years;
    }

}